﻿using System.Linq;
using System.Windows;
using XEvolve.Core.Runtime;
using XEvolve.Core.Runtime.Attributes;

namespace XEvolve.Presentation.Internal
{
    internal class ThemeManager : IThemeManager
    {
        private readonly IExtensionPoint themes;
        private readonly ColorSchema[] themeColorSchema;

        public ThemeManager([ExtensionPoint("xevolve.themes")] IExtensionPoint themes,
                            [Extensions("xevolve.themes.colorSchema")] ColorSchema[] themeColorSchema)
        {
            this.themes = themes;
            this.themeColorSchema = themeColorSchema;
        }

        private ResourceDictionary this[object key]
        {
            get { return (ResourceDictionary) themes.GetExtension(key); }
        }

        public string[] GetApplicableColorSchema(string themeName)
        {
            return themeColorSchema.Where(schema => schema.IsApplicable(themeName)).Select(schema => schema.Name).ToArray();
        }

        public void ApplyTheme(string themeName)
        {
            ApplyTheme(themeName, null);
        }


        public void ApplyTheme(string themeName, string colorSchemaName)
        {
            var application = Application.Current;
            if (application == null) return;
            application.Resources = GetThemeResources(themeName, colorSchemaName);
        }

        public void ApplyTheme(FrameworkElement target, string themeName)
        {
            ApplyTheme(target, themeName, null);
        }

        public void ApplyTheme(FrameworkElement target, string themeName, string colorSchemaName)
        {
            if (target == null) return;
            target.Resources = GetThemeResources(themeName, colorSchemaName);
        }

        private ResourceDictionary GetThemeResources(string themeName, string colorSchemaName)
        {
            var theme = this[themeName];
            if (theme == null) return null;
            var themeResources = new ResourceDictionary();
            themeResources.MergedDictionaries.Add(theme);

            if (colorSchemaName != null)
            {
                var colorSchema =
                    themeColorSchema.SingleOrDefault(
                        schema => schema.Name.Equals(colorSchemaName) && schema.IsApplicable(themeName));
                if (colorSchema != null)
                {
                    themeResources.MergedDictionaries.Add(colorSchema.ResourceDictionary);
                }
            }
            return themeResources;
        }
    }
}